using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Model.Utils
{
    /// <summary>
    /// 简化的实体生成工具类
    /// 使用 SQL 查询直接获取表结构，生成标准的实体类
    /// </summary>
    public class SimpleEntityGenerator
    {
        /// <summary>
        /// 生成指定表的实体类
        /// </summary>
        /// <param name="tableNames">要生成实体的表名数组</param>
        /// <param name="namespaceName">命名空间名称</param>
        /// <param name="outputPath">输出路径</param>
        /// <returns>生成结果</returns>
        public static SimpleEntityGenerationResult GenerateEntities(string[] tableNames, string namespaceName = "Model", string outputPath = null)
        {
            try
            {
                // 设置输出路径
                if (string.IsNullOrEmpty(outputPath))
                {
                    outputPath = GetModelProjectPath();
                }
                
                // 确保目录存在
                if (!Directory.Exists(outputPath))
                {
                    Directory.CreateDirectory(outputPath);
                }
                
                var generatedFiles = new List<string>();
                var successTables = new List<string>();
                var failedTables = new List<string>();
                
                // 逐个生成每个表的实体
                foreach (var tableName in tableNames)
                {
                    try
                    {
                        // 获取表结构信息
                        var columns = GetTableColumns(tableName);
                        
                        if (columns.Count == 0)
                        {
                            failedTables.Add(tableName);
                            continue;
                        }
                        
                        // 生成实体类代码
                        var entityCode = GenerateEntityCode(tableName, columns, namespaceName);
                        
                        // 保存到文件
                        var className = ConvertTableNameToClassName(tableName);
                        var fileName = $"{className}.cs";
                        var filePath = Path.Combine(outputPath, fileName);
                        
                        File.WriteAllText(filePath, entityCode, Encoding.UTF8);
                        
                        generatedFiles.Add(fileName);
                        successTables.Add(tableName);
                        
                        // 强制垃圾回收
                        GC.Collect();
                        GC.WaitForPendingFinalizers();
                    }
                    catch (Exception ex)
                    {
                        failedTables.Add(tableName);
                        Console.WriteLine($"生成表 {tableName} 失败: {ex.Message}");
                    }
                }
                
                return new SimpleEntityGenerationResult
                {
                    Success = successTables.Count > 0,
                    Message = $"成功生成 {successTables.Count} 个表，失败 {failedTables.Count} 个表",
                    OutputPath = outputPath,
                    GeneratedFiles = generatedFiles.ToArray(),
                    TableNames = successTables.ToArray(),
                    FailedTables = failedTables.ToArray()
                };
            }
            catch (Exception ex)
            {
                return new SimpleEntityGenerationResult
                {
                    Success = false,
                    Message = "生成实体失败",
                    Error = ex.Message,
                    StackTrace = ex.StackTrace
                };
            }
        }
        
        /// <summary>
        /// 获取表的列信息
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns>列信息列表</returns>
        private static List<ColumnInfo> GetTableColumns(string tableName)
        {
            try
            {
                // 使用简单的连接字符串
                var connectionString = "Server=localhost;Database=srb;Uid=root;Pwd=0501;Port=3306;Charset=utf8;";
                
                using (var db = new SqlSugarClient(new ConnectionConfig
                {
                    ConnectionString = connectionString,
                    DbType = SqlSugar.DbType.MySql,
                    IsAutoCloseConnection = true
                }))
                {
                    var sql = @"
                        SELECT 
                            COLUMN_NAME as ColumnName,
                            DATA_TYPE as DataType,
                            IS_NULLABLE as IsNullable,
                            COLUMN_DEFAULT as DefaultValue,
                            COLUMN_KEY as ColumnKey,
                            EXTRA as Extra,
                            COLUMN_COMMENT as Comment
                        FROM INFORMATION_SCHEMA.COLUMNS 
                        WHERE TABLE_SCHEMA = DATABASE() 
                        AND TABLE_NAME = @tableName
                        ORDER BY ORDINAL_POSITION";
                    
                    var columns = db.Ado.SqlQuery<ColumnInfo>(sql, new { tableName });
                    return columns.ToList();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取表 {tableName} 列信息失败: {ex.Message}");
                return new List<ColumnInfo>();
            }
        }
        
        /// <summary>
        /// 生成实体类代码
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columns">列信息</param>
        /// <param name="namespaceName">命名空间</param>
        /// <returns>实体类代码</returns>
        private static string GenerateEntityCode(string tableName, List<ColumnInfo> columns, string namespaceName)
        {
            var className = ConvertTableNameToClassName(tableName);
            var sb = new StringBuilder();
            
            // 添加 using 语句
            sb.AppendLine("using SqlSugar;");
            sb.AppendLine("using System;");
            sb.AppendLine();
            
            // 添加命名空间
            sb.AppendLine($"namespace {namespaceName}");
            sb.AppendLine("{");
            
            // 添加类注释
            sb.AppendLine("    /// <summary>");
            sb.AppendLine($"    /// {tableName} 表实体类");
            sb.AppendLine("    /// </summary>");
            
            // 添加 SugarTable 特性
            sb.AppendLine($"    [SugarTable(\"{tableName}\")]");
            sb.AppendLine($"    public class {className}");
            sb.AppendLine("    {");
            
            // 添加属性
            foreach (var column in columns)
            {
                var propertyName = ConvertColumnNameToPropertyName(column.ColumnName);
                var propertyType = ConvertDataTypeToCSharpType(column.DataType, column.IsNullable == "YES");
                
                // 添加属性注释
                if (!string.IsNullOrEmpty(column.Comment))
                {
                    sb.AppendLine($"        /// <summary>");
                    sb.AppendLine($"        /// {column.Comment}");
                    sb.AppendLine($"        /// </summary>");
                }
                
                // 添加 SugarColumn 特性
                var sugarColumnAttributes = new List<string>();
                
                if (column.ColumnKey == "PRI")
                {
                    sugarColumnAttributes.Add("IsPrimaryKey = true");
                }
                
                if (column.Extra == "auto_increment")
                {
                    sugarColumnAttributes.Add("IsIdentity = true");
                }
                
                if (column.ColumnName != propertyName)
                {
                    sugarColumnAttributes.Add($"ColumnName = \"{column.ColumnName}\"");
                }
                
                if (sugarColumnAttributes.Count > 0)
                {
                    sb.AppendLine($"        [SugarColumn({string.Join(", ", sugarColumnAttributes)})]");
                }
                
                // 添加属性
                sb.AppendLine($"        public {propertyType} {propertyName} {{ get; set; }}");
                sb.AppendLine();
            }
            
            // 结束类
            sb.AppendLine("    }");
            sb.AppendLine("}");
            
            return sb.ToString();
        }
        
        /// <summary>
        /// 将数据类型转换为 C# 类型
        /// </summary>
        /// <param name="dataType">数据库数据类型</param>
        /// <param name="isNullable">是否可空</param>
        /// <returns>C# 类型</returns>
        private static string ConvertDataTypeToCSharpType(string dataType, bool isNullable)
        {
            var typeMapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
            {
                { "tinyint", "byte" },
                { "smallint", "short" },
                { "mediumint", "int" },
                { "int", "int" },
                { "integer", "int" },
                { "bigint", "long" },
                { "decimal", "decimal" },
                { "numeric", "decimal" },
                { "float", "float" },
                { "double", "double" },
                { "char", "string" },
                { "varchar", "string" },
                { "text", "string" },
                { "mediumtext", "string" },
                { "longtext", "string" },
                { "date", "DateTime" },
                { "datetime", "DateTime" },
                { "timestamp", "DateTime" },
                { "time", "TimeSpan" },
                { "year", "int" },
                { "binary", "byte[]" },
                { "varbinary", "byte[]" },
                { "blob", "byte[]" },
                { "mediumblob", "byte[]" },
                { "longblob", "byte[]" },
                { "bit", "bool" },
                { "json", "string" }
            };
            
            // 提取基础类型（去掉长度信息）
            var baseType = dataType.Split('(')[0].ToLower();
            
            if (typeMapping.TryGetValue(baseType, out var csharpType))
            {
                // 如果是可空类型且不是 string 或 byte[]
                if (isNullable && csharpType != "string" && csharpType != "byte[]")
                {
                    return $"{csharpType}?";
                }
                return csharpType;
            }
            
            // 默认返回 string
            return "string";
        }
        
        /// <summary>
        /// 将列名转换为属性名
        /// </summary>
        /// <param name="columnName">列名</param>
        /// <returns>属性名</returns>
        private static string ConvertColumnNameToPropertyName(string columnName)
        {
            if (string.IsNullOrEmpty(columnName))
                return string.Empty;
            
            // 将下划线分隔的单词转换为PascalCase
            var parts = columnName.Split('_');
            var propertyName = string.Join("", parts.Select(part => 
                char.ToUpper(part[0]) + part.Substring(1).ToLower()));
            
            return propertyName;
        }
        
        /// <summary>
        /// 将表名转换为类名
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns>类名</returns>
        private static string ConvertTableNameToClassName(string tableName)
        {
            if (string.IsNullOrEmpty(tableName))
                return string.Empty;
            
            // 移除表名前缀（如果有的话）
            var name = tableName;
            if (name.StartsWith("t_") || name.StartsWith("tb_"))
            {
                name = name.Substring(2);
            }
            
            // 将下划线分隔的单词转换为PascalCase
            var parts = name.Split('_');
            var className = string.Join("", parts.Select(part => 
                char.ToUpper(part[0]) + part.Substring(1).ToLower()));
            
            return className;
        }
        
        /// <summary>
        /// 获取Model项目路径
        /// </summary>
        /// <returns>Model项目路径</returns>
        private static string GetModelProjectPath()
        {
            // 获取当前程序集所在目录
            var currentDirectory = AppDomain.CurrentDomain.BaseDirectory;
            
            // 查找Model项目目录
            var modelPath = Path.Combine(currentDirectory, "..", "..", "..", "Model");
            
            // 如果找不到，尝试其他可能的路径
            if (!Directory.Exists(modelPath))
            {
                modelPath = Path.Combine(currentDirectory, "Model");
            }
            
            if (!Directory.Exists(modelPath))
            {
                // 如果还是找不到，使用当前目录下的Model文件夹
                modelPath = Path.Combine(currentDirectory, "Model");
                Directory.CreateDirectory(modelPath);
            }
            
            return modelPath;
        }
        
        /// <summary>
        /// 测试数据库连接
        /// </summary>
        /// <returns>连接测试结果</returns>
        public static SimpleConnectionTestResult TestConnection()
        {
            try
            {
                var connectionString = "Server=localhost;Database=srb;Uid=root;Pwd=0501;Port=3306;Charset=utf8;";
                
                using (var db = new SqlSugarClient(new ConnectionConfig
                {
                    ConnectionString = connectionString,
                    DbType = SqlSugar.DbType.MySql,
                    IsAutoCloseConnection = true
                }))
                {
                    // 测试连接
                    var result = db.Ado.GetDataTable("SELECT 1 as Test");
                    
                    return new SimpleConnectionTestResult
                    {
                        Success = true,
                        Message = "数据库连接成功",
                        ConnectionString = connectionString,
                        TestResult = result.Rows.Count > 0 ? "连接正常" : "连接异常"
                    };
                }
            }
            catch (Exception ex)
            {
                return new SimpleConnectionTestResult
                {
                    Success = false,
                    Message = "数据库连接失败",
                    Error = ex.Message,
                    ConnectionString = "Server=localhost;Database=srb;Uid=root;Pwd=0501;Port=3306;Charset=utf8;"
                };
            }
        }
    }
    
    /// <summary>
    /// 列信息
    /// </summary>
    public class ColumnInfo
    {
        public string ColumnName { get; set; }
        public string DataType { get; set; }
        public string IsNullable { get; set; }
        public string DefaultValue { get; set; }
        public string ColumnKey { get; set; }
        public string Extra { get; set; }
        public string Comment { get; set; }
    }
    
    /// <summary>
    /// 简化实体生成结果
    /// </summary>
    public class SimpleEntityGenerationResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        
        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }
        
        /// <summary>
        /// 错误信息
        /// </summary>
        public string Error { get; set; }
        
        /// <summary>
        /// 堆栈跟踪
        /// </summary>
        public string StackTrace { get; set; }
        
        /// <summary>
        /// 输出路径
        /// </summary>
        public string OutputPath { get; set; }
        
        /// <summary>
        /// 生成的文件列表
        /// </summary>
        public string[] GeneratedFiles { get; set; }
        
        /// <summary>
        /// 表名列表
        /// </summary>
        public string[] TableNames { get; set; }
        
        /// <summary>
        /// 失败的表名列表
        /// </summary>
        public string[] FailedTables { get; set; }
    }
    
    /// <summary>
    /// 简化连接测试结果
    /// </summary>
    public class SimpleConnectionTestResult
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        
        /// <summary>
        /// 消息
        /// </summary>
        public string Message { get; set; }
        
        /// <summary>
        /// 错误信息
        /// </summary>
        public string Error { get; set; }
        
        /// <summary>
        /// 连接字符串
        /// </summary>
        public string ConnectionString { get; set; }
        
        /// <summary>
        /// 测试结果
        /// </summary>
        public string TestResult { get; set; }
    }
}